#include "ProtocolParser.h"
#include <QStringList>
#include <QDebug>
#include <QRegularExpression>

ProtocolParser::ProtocolParser(QObject *parent) : QObject(parent)
{
}

QByteArray ProtocolParser::buildPacket(const QString &qn, int cn, int flag, const QMap<QString, QString> &params)
{
    // 1. 构建数据段
    QByteArray dataSegment = buildDataSegment(qn, cn, flag, params);
    if (dataSegment.isEmpty()) {
        qDebug() << "Failed to build data segment";
        return QByteArray();
    }

    // 2. 构建包头和长度字段
    QByteArray headerAndLength = "##";
    QString lengthStr = QString("%1").arg(dataSegment.length(), 4, 10, QLatin1Char('0'));
    headerAndLength += lengthStr.toUtf8();

    // 3. CRC计算的是：包头 + 长度 + 数据段 (##0042 + 数据段)
    QByteArray crcData = headerAndLength + dataSegment;
    quint16 crc = calculateCRC16(crcData);

    // 4. 构建完整报文
    QByteArray packet = crcData;  // 已经包含##0042+数据段
    QString crcStr = QString("%1").arg(crc, 4, 16, QLatin1Char('0')).toUpper();
    packet += crcStr.toUtf8();
    packet += "\r\n";

    qDebug() << "=== 报文构建调试 ===";
    qDebug() << "数据段:" << QString(dataSegment);
    qDebug() << "CRC:" << crcStr;

    return packet;
}

bool ProtocolParser::parsePacket(const QByteArray &packet, QByteArray &dataSegment)
{
    // 检查最小长度
    if (packet.length() < 12) {
        qDebug() << "Packet too short";
        return false;
    }

    // 检查包头
    if (packet.left(2) != "##") {
        qDebug() << "Invalid packet header";
        return false;
    }

    // 检查包尾
    if (packet.right(2) != "\r\n") {
        qDebug() << "Invalid packet footer";
        return false;
    }

    // 提取数据段长度
    bool ok;
    int dataLength = packet.mid(2, 4).toInt(&ok);
    if (!ok || dataLength < 0 || dataLength > 1024) {
        qDebug() << "Invalid data length:" << dataLength;
        return false;
    }

    // 检查总长度：头(2) + 长度(4) + 数据段 + CRC(4) + 尾(2)
    int expectedLength = 2 + 4 + dataLength + 4 + 2;
    if (packet.length() != expectedLength) {
        qDebug() << "Packet length mismatch, expected:" << expectedLength
                 << "actual:" << packet.length();
        return false;
    }

    // 提取数据段
    dataSegment = packet.mid(6, dataLength);

    // 提取CRC校验
    quint16 receivedCrc = packet.mid(6 + dataLength, 4).toUShort(&ok, 16);
    if (!ok) {
        qDebug() << "Invalid CRC format";
        return false;
    }

    // 计算CRC并验证
    QByteArray crcData = packet.mid(0, 6 + dataLength); // ## + 长度(4字节) + 数据段
    quint16 calculatedCrc = calculateCRC16(crcData);

    if (receivedCrc != calculatedCrc) {
        qDebug() << "CRC mismatch: received" << QString::number(receivedCrc, 16)
        << "calculated" << QString::number(calculatedCrc, 16);
        qDebug() << "CRC计算数据:" << crcData.toHex();
        return false;
    }

    return true;
}

bool ProtocolParser::parseDataSegment(const QByteArray &data, QString &qn, int &cn, int &flag, QMap<QString, QString> &params)
{
    QString dataStr = QString::fromUtf8(data);

    // 使用正则表达式解析字段
    QRegularExpression qnRegex("QN=([^;]+)");
    QRegularExpression cnRegex("CN=([^;]+)");
    QRegularExpression flagRegex("Flag=([^;]+)");
    QRegularExpression cpRegex("CP=&&([^&]*)&&");

    QRegularExpressionMatch qnMatch = qnRegex.match(dataStr);
    QRegularExpressionMatch cnMatch = cnRegex.match(dataStr);
    QRegularExpressionMatch flagMatch = flagRegex.match(dataStr);
    QRegularExpressionMatch cpMatch = cpRegex.match(dataStr);

    // 解析QN
    if (qnMatch.hasMatch()) {
        qn = qnMatch.captured(1);
        // 验证QN格式 (yyyyMMddHHmmssfff)
        QRegularExpression qnFormat("\\d{17}");
        if (!qnFormat.match(qn).hasMatch()) {
            qDebug() << "Invalid QN format:" << qn;
            return false;
        }
    } else {
        qDebug() << "Missing QN field";
        return false;
    }

    // 解析CN
    if (cnMatch.hasMatch()) {
        cn = cnMatch.captured(1).toInt();
        // 验证CN范围
        if (cn < 100 || cn > 904) {
            qDebug() << "Invalid CN value:" << cn;
            return false;
        }
    } else {
        qDebug() << "Missing CN field";
        return false;
    }

    // 解析Flag
    if (flagMatch.hasMatch()) {
        flag = flagMatch.captured(1).toInt();
    } else {
        qDebug() << "Missing Flag field";
        return false;
    }

    // 解析CP
    if (cpMatch.hasMatch()) {
        QString cp = cpMatch.captured(1);
        params = parseCP(cp);
    }

    return true;
}

QByteArray ProtocolParser::buildDataSegment(const QString &qn, int cn, int flag, const QMap<QString, QString> &params)
{
    // 验证输入参数
    if (qn.length() != 17) {
        qDebug() << "Invalid QN length, must be 17 characters, got:" << qn.length();
        return QByteArray();
    }

    if (cn < 100 || cn > 904) {
        qDebug() << "Invalid CN value:" << cn;
        return QByteArray();
    }

    // 构建基础数据段
    QString dataSegment = QString("QN=%1;CN=%2;Flag=%3").arg(qn).arg(cn).arg(flag);

    if (!params.isEmpty()) {
        QString cp = buildCP(params);
        dataSegment += ";CP=&&" + cp + "&&";
    } else {
        dataSegment += ";CP=&&&&";
    }

    qDebug() << "Data segment:" << dataSegment;
    qDebug() << "Data segment length:" << dataSegment.length();

    return dataSegment.toUtf8();
}

QString ProtocolParser::getCurrentTimestamp()
{
    return QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
}

QMap<QString, QString> ProtocolParser::parseCP(const QString &cp)
{
    QMap<QString, QString> params;
    QStringList pairs = cp.split(",");

    for (const QString &pair : pairs) {
        QStringList keyValue = pair.split("=");
        if (keyValue.size() == 2) {
            QString key = keyValue[0].trimmed();
            QString value = keyValue[1].trimmed();

            // 更新有效字段列表，添加 NO 和 Count
            static const QStringList validFields = {
                "ExeRtn", "QnRtn", "D", "R", "S", "H", "V", "I",
                "SX", "SY", "SZ", "EX", "EY", "EZ", "NO", "Count",  // 添加 NO 和 Count
                "State", "DA", "IOBits", "CKSM"
            };

            if (!validFields.contains(key)) {
                qDebug() << "Unknown field in CP:" << key;
                continue;
            }

            params[key] = value;
        }
    }

    return params;
}

QString ProtocolParser::buildCP(const QMap<QString, QString> &params)
{
    if (params.isEmpty()) {
        return "";
    }

    // 数据应答包的特殊处理：DA在前，NO在后，用分号分隔
    if (params.contains("DA")) {
        QStringList pairs;

        // DA 必须放在第一位
        pairs.append("DA=" + params["DA"]);

        // NO 放在第二位（如果有）
        if (params.contains("NO")) {
            pairs.append("NO=" + params["NO"]);
        }

        // 用分号分隔
        return pairs.join(";");
    }

    static const QStringList paramOrder = {
        "SX", "SY", "SZ", "EX", "EY", "EZ",  // 运动坐标
        "V", "R",                            // 运动参数
        "D", "S", "H", "FV",                 // 工艺参数
        "IOBits", "NO", "Count", "State",    // 控制参数（添加 NO 和 Count）
        "ExeRtn", "QnRtn",                   // 响应参数
        "DA", "CKSM", "I"                    // 其他参数
    };

    QStringList pairs;

    for (const QString &key : paramOrder) {
        if (params.contains(key)) {
            pairs.append(key + "=" + params[key]);
        }
    }

    return pairs.join(",");
}

quint16 ProtocolParser::calculateCRC16(const QByteArray &data)
{
    // 使用C#服务端的确切CRC16-CCITT算法
    // 初始值: 0xFFFF, 多项式: 0x1021
    quint16 crc = 0xFFFF;
    quint16 polynomial = 0x1021;

    for (int i = 0; i < data.length(); ++i) {
        quint8 byte = static_cast<quint8>(data[i]);
        crc ^= (static_cast<quint16>(byte) << 8);

        for (int j = 0; j < 8; j++) {
            if (crc & 0x8000) {
                crc = (crc << 1) ^ polynomial;
            } else {
                crc <<= 1;
            }
        }
    }

    return crc;
}
